package com.xyz.rok.tools.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author ZhangYiXin
 * @version 1.0
 * @date 2021/7/1 14:25
 **/
@Component
@Slf4j
public class JwtUtil {


    private static final long EXP = 24 * 60 * 60 * 1000 * 360L;
    private static final String ISSUER = "xyz";
    private static final String AUDIENCE = "miniprogram";

    @Value("${jwt.token:iGDxYU6zj*R7R$n2}")
    private String secret;

    public static void main(String[] args) throws InterruptedException {
        JwtUtil jwtUtil = new JwtUtil();
        String token = jwtUtil.createToken();
        System.out.println(token);
    }

    public String createToken(TokenPayload tokenPayload) {
        Map<String, Object> payload = new HashMap(16);
        if (tokenPayload != null) {
            if (tokenPayload.getUserId() != null) {
                payload.put("userId", tokenPayload.getUserId());
            }
            if (tokenPayload.getUnionIds() != null && !tokenPayload.getUnionIds().isEmpty()) {
                payload.put("unionIds", tokenPayload.getUnionIds());
            }
        }
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            String token = JWT.create()
                    .withIssuer(ISSUER)
                    .withAudience(AUDIENCE)
                    .withExpiresAt(new Date(System.currentTimeMillis() + EXP))
                    .withIssuedAt(new Date())
                    .withPayload(payload)
                    .sign(algorithm);
            return token;
        } catch (JWTCreationException e) {
            log.error("createToken error", e);
            return null;
        }
    }

    public String createToken() {
        return createToken(null);
    }

    public TokenPayload verifierToken(String uri, String token) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(secret);
            JWTVerifier verifier = JWT.require(algorithm)
                    .withIssuer(ISSUER)
                    .build();
            DecodedJWT jwt = verifier.verify(token);
            Long userId = jwt.getClaim("userId").as(Long.class);
            List<Long> unionIds = jwt.getClaim("unionIds").asList(Long.class);
            TokenPayload tokenPayload = new TokenPayload();
            tokenPayload.setUserId(userId);
            tokenPayload.setUnionIds(unionIds);
            return tokenPayload;
        } catch (JWTVerificationException e) {
            log.error("token:{} verifierToken error,uri:{}", token, uri, e);
            return null;
        }
    }


}
